/**
 * Vue 3 兼容性工具函数
 * 解决微信小程序中 ctx 为 null 的问题
 */

import { getCurrentInstance, nextTick } from 'vue'

/**
 * 安全地获取组件实例
 * @returns {Object|null} 组件实例或null
 */
export function getSafeInstance() {
  try {
    const instance = getCurrentInstance()
    return instance?.proxy || instance?.ctx || null
  } catch (error) {
    console.warn('获取组件实例失败:', error)
    return null
  }
}

/**
 * 安全地访问 $refs
 * @param {string} refName - ref名称
 * @param {Object} context - 组件上下文，可选
 * @returns {Object|null} ref对象或null
 */
export function safeGetRef(refName, context = null) {
  try {
    const instance = context || getSafeInstance()
    if (!instance) {
      console.warn(`无法获取组件实例，ref: ${refName}`)
      return null
    }
    
    const refs = instance.$refs || instance.refs
    if (!refs) {
      console.warn(`$refs 不可用，ref: ${refName}`)
      return null
    }
    
    const ref = refs[refName]
    if (!ref) {
      console.warn(`ref 不存在: ${refName}`)
      return null
    }
    
    return ref
  } catch (error) {
    console.error(`访问 ref 失败: ${refName}`, error)
    return null
  }
}

/**
 * 安全地调用 ref 方法
 * @param {string} refName - ref名称
 * @param {string} methodName - 方法名
 * @param {Array} args - 方法参数
 * @param {Object} context - 组件上下文，可选
 * @returns {any} 方法返回值或null
 */
export function safeCallRefMethod(refName, methodName, args = [], context = null) {
  try {
    const ref = safeGetRef(refName, context)
    if (!ref) {
      return null
    }
    
    const method = ref[methodName]
    if (typeof method !== 'function') {
      console.warn(`方法不存在或不是函数: ${refName}.${methodName}`)
      return null
    }
    
    return method.apply(ref, args)
  } catch (error) {
    console.error(`调用 ref 方法失败: ${refName}.${methodName}`, error)
    return null
  }
}

/**
 * 安全地访问 $api
 * @param {Object} context - 组件上下文，可选
 * @returns {Object|null} api对象或null
 */
export function safeGetApi(context = null) {
  try {
    const instance = context || getSafeInstance()
    if (!instance) {
      console.warn('无法获取组件实例，$api 不可用')
      return null
    }
    
    const api = instance.$api
    if (!api) {
      console.warn('$api 不可用')
      return null
    }
    
    return api
  } catch (error) {
    console.error('访问 $api 失败', error)
    return null
  }
}

/**
 * 安全地调用 API 方法
 * @param {string} apiPath - API路径，如 'goods.getGoodsList'
 * @param {Array} args - 方法参数
 * @param {Object} context - 组件上下文，可选
 * @returns {Promise|null} API调用结果或null
 */
export function safeCallApi(apiPath, args = [], context = null) {
  try {
    const api = safeGetApi(context)
    if (!api) {
      return null
    }
    
    const pathParts = apiPath.split('.')
    let method = api
    
    for (const part of pathParts) {
      if (!method || typeof method !== 'object') {
        console.warn(`API路径无效: ${apiPath}`)
        return null
      }
      method = method[part]
    }
    
    if (typeof method !== 'function') {
      console.warn(`API方法不存在或不是函数: ${apiPath}`)
      return null
    }
    
    return method.apply(null, args)
  } catch (error) {
    console.error(`调用 API 失败: ${apiPath}`, error)
    return null
  }
}

/**
 * 安全地使用 nextTick
 * @param {Function} callback - 回调函数
 * @returns {Promise}
 */
export function safeNextTick(callback) {
  return nextTick(() => {
    try {
      if (typeof callback === 'function') {
        callback()
      }
    } catch (error) {
      console.error('nextTick 回调执行失败:', error)
    }
  })
}

/**
 * 创建安全的事件处理器
 * @param {Function} handler - 原始事件处理器
 * @param {Object} context - 组件上下文，可选
 * @returns {Function} 安全的事件处理器
 */
export function createSafeHandler(handler, context = null) {
  return function(...args) {
    try {
      const instance = context || getSafeInstance()
      if (!instance) {
        console.warn('组件实例不可用，跳过事件处理')
        return
      }
      
      return handler.apply(instance, args)
    } catch (error) {
      console.error('事件处理器执行失败:', error)
    }
  }
}

/**
 * 延迟执行函数，确保组件已挂载
 * @param {Function} fn - 要执行的函数
 * @param {number} delay - 延迟时间（毫秒）
 * @param {Object} context - 组件上下文，可选
 */
export function safeDelayedCall(fn, delay = 100, context = null) {
  setTimeout(() => {
    try {
      const instance = context || getSafeInstance()
      if (instance && typeof fn === 'function') {
        fn.call(instance)
      }
    } catch (error) {
      console.error('延迟调用失败:', error)
    }
  }, delay)
}

/**
 * 检查组件是否已挂载
 * @param {Object} context - 组件上下文，可选
 * @returns {boolean} 是否已挂载
 */
export function isComponentMounted(context = null) {
  try {
    const instance = context || getSafeInstance()
    return !!(instance && (instance.$refs || instance.refs))
  } catch (error) {
    console.error('检查组件挂载状态失败:', error)
    return false
  }
}